/* eslint-disable no-unused-vars */
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const UglifyJSPlugin = require('uglifyjs-webpack-plugin')
const webpack = require('webpack')
const fs = require('fs')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CleanWebpackPlugin = require('clean-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const LodashModuleReplacementPlugin = require('lodash-webpack-plugin')
const CompressionWebpackPlugin = require('compression-webpack-plugin')
const PATH = require('path')
const dist = PATH.resolve(__dirname, './dist')
// const distm = PATH.resolve(__dirname, './application/themes/mobile/assets/dist');
const VIEW = PATH.join(__dirname, './public')
const ENV = {
    'watch': {

    }
}
// config
// build的时候是否显示报告
const REPORT = true
// @代表/ 表示下一个文件夹
// 排除的文件
const EXCLUDE = []

// 入口
const ENTRY = {
    index: '@/index.ts'
    // -- APPEND ITEMS HERE --
}
// const tmp = {};
// for (const i of Object.keys(ENTRY)) {
//     tmp[i] = [
//         'babel-polyfill',
//         'whatwg-fetch',
//         ENTRY[i]
//     ];
// }
// ENTRY = tmp;
// 通用chunk
// const COMMONCHUNKS = ["app"];
const COMMONCHUNKS = []

function resolve(dir) {
    return PATH.join(__dirname, dir)
}
module.exports = function(env, argv) {
    // VIEW = VIEW === false ? '' : VIEW || dfview

    // dist = dist === false ? '' : dist || dfdist
    env = env || 'development'

    function readDirSync(path) {
        let ret = []
        const pa = fs.readdirSync(path)
        pa.forEach(function(ele) {
            const info = fs.statSync(path + '/' + ele)
            if (info.isDirectory()) {
                ret = ret.concat(readDirSync(PATH.join(path, ele)))
            } else {
                ret = ret.concat(PATH.join(path, ele))
            }
        })
        return ret
    }

    function getview(path) {
        const ret = []
        const basepath = PATH.join(path)
        if (!fs.existsSync(basepath)) {
            return ret
        }
        let stat = fs.lstatSync(basepath)
        if (!stat.isDirectory()) {
            return ret
        }
        const files = readDirSync(basepath)
        files.forEach(v => {
            const chunk = v.replace(path, '').replace(/^[\\/]/, '').replace(/[\\/]/, '@').split('.').shift()

            // const chunk = PATH.basename(v)
            let chunks = []
            if (EXCLUDE.indexOf(chunk) == -1) {
                chunks = COMMONCHUNKS.concat([chunk])
            }
            const t = new HtmlWebpackPlugin({
                filename: v.replace(basepath, ''),
                template: v,
                chunks: chunks,
                hash: false,
                inject: true,
                chunksSortMode: 'auto',
                minify: false
            })
            ret.push(t)
        })
        return ret
    }

    const DEVSERVER = argv.ishot ? {
        contentBase: PATH.join(dist),
        hot: true,
        watchContentBase: true,
        openPage: 'index.html',
        // open: true,
        port: 9002,
        inline: true,
        host: '127.0.0.1'
    } : {}
    // 插件
    const PLUGINS = (function() {
        var plugins = [

        ]
        plugins.push(new CleanWebpackPlugin(dist))
        plugins.push(new VueLoaderPlugin())

        plugins.push(new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify(env)
        }))
        plugins.push(new LodashModuleReplacementPlugin())
        plugins.push(new webpack.ProvidePlugin({
            '_': 'lodash',
            '$': 'jquery',
            'jQuery': 'jquery',
            'window.jQuery': 'jquery',
            'window.$': 'jquery'
        }))

        if (argv.ishot) {
            plugins.push(new webpack.NamedModulesPlugin())
            plugins.push(new webpack.HotModuleReplacementPlugin())
        }
        // 从view目录读取文件并注入和文件名字对应的js
        plugins = plugins.concat(getview(VIEW))
        plugins.push(
            // new HtmlWebpackPlugin({
            //     filename: '/view/index.php',
            //     template: resolve('./src/view/index.html'),
            //     hash: false,
            //     inject: true,
            //     chunksSortMode: 'auto',
            //     minify: false
            // }),
            // new HtmlWebpackPlugin({
            //     filename: "user.html",
            //     template: "./TJDX/A.html",
            //     chunks: ["user"]
            // }),
        )
        plugins.push(new MiniCssExtractPlugin({
            filename: env == 'development' ? 'css/[name].css' : 'css/[name].[chunkHash:5].css',
            sourceMap: false
        }))
        // build的时候用到的插件
        var buildPlugins = [
            new CompressionWebpackPlugin({
                filename: '[path].gz[query]', // 目标文件名
                algorithm: 'gzip', // 使用gzip压缩
                test: /.(js|css|svg|woff|ttf|json|html)$/,
                threshold: 10240, // 资源文件大于10240B=10kB时会被压缩
                minRatio: 0.8 // 最小压缩比达到0.8时才会被压缩
            }),
            new webpack.optimize.SplitChunksPlugin({
                chunks: 'all',
                minSize: 30000,
                minChunks: 1,
                maxAsyncRequests: 5,
                maxInitialRequests: 3,
                automaticNameDelimiter: '~',
                name: true,
                cacheGroups: {
                    default: {
                        minChunks: 3,
                        priority: -20,
                        reuseExistingChunk: true
                    },
                    vendors: {
                        test: /[\\/]node_modules[\\/]/,
                        priority: -10,
                        name: 'vendor'
                    },
                    bootstrapv: {
                        test: /[\\/]node_modules[\\/]bootstrap-vue/,
                        priority: 10,
                        name: 'bootstrapv'
                    },
                    xlsx: {
                        test: /[\\/]node_modules[\\/]xlsx/,
                        priority: 10,
                        name: 'xlsx'
                    }
                }
            }),
            new webpack.optimize.RuntimeChunkPlugin({
                name: 'runtime'
            }),
            new UglifyJSPlugin({
                parallel: false,
                cache: false,
                // extractComments: true,
                uglifyOptions: {
                    comments: true, // 删除所有的注释
                    compress: {
                        warnings: false, // 在UglifyJs删除没有用到的代码时不输出警告
                        drop_console: true, // 删除所有的 `console` 语句 还可以兼容ie浏览器
                        collapse_vars: true, // 内嵌定义了但是只用到一次的变量
                        reduce_vars: true // 提取出出现多次但是没有定义成变量去引用的静态值
                    }
                }
            })

        ]

        env == 'production' && REPORT ? plugins.push(new BundleAnalyzerPlugin({
            analyzerMode: 'static',
            openAnalyzer: false
        })) : ''
        return env == 'production' ? plugins.concat(buildPlugins) : plugins
    })()
    // 代码显示模式
    const DEVTOOL = (() => {
        return env == 'production' ? '' : 'eval-source-map'
    })()
    // 环境
    const MODE = (() => {
        return env
    })()

    const ret = {
        externals: {
            // jquery: 'jQuery'
            // vue: 'Vue'
        },
        entry: ENTRY,
        target: 'web',
        output: {
            filename: env == 'development' ? 'js/[name].js' : 'js/[name].[chunkHash:5].js',
            // path: dist,
            publicPath: '/'
        },
        resolve: {
            extensions: ['.js', '.vue', '.json', '.ts', '.tsx'],
            alias: {
                'vue$': 'vue/dist/vue.common.js',
                '@': resolve('src')
                // 'bootstrap-vue$': 'bootstrap-vue/src/index.js'
            }
        },
        module: {
            rules: [{
                test: /\.(js|ts|tsx)$/,
                // Exclude transpiling `node_modules`, except `bootstrap-vue/src`
                exclude: /node_modules\/(?!bootstrap-vue\/src\/)/,
                use: {
                    loader: 'babel-loader'
                }
            }, /* ,            {
                test: /\.(ts|tsx)$/,
                // Exclude transpiling `node_modules`, except `bootstrap-vue/src`
                exclude: /node_modules/,
                use: [{
                    loader: 'babel-loader'
                },
                {
                    loader: 'ts-loader'
                }]
            } */
            {
                test: /\.vue$/,
                // exclude: /node_modules/,
                // include:/src[\\/].*|(.*[\\/]iview)/,
                loader: 'vue-loader'
            },
            {
                test: /\.(png|svg|jpg|gif)$/,
                use: [{
                    loader: 'url-loader',
                    options: {
                        limit: 1000,
                        name: 'images/[name].[ext]',
                        // outputPath: '../images',
                        publicPath: '../'
                    }
                }]
            },
            {
                test: /\.(woff|woff2|eot|ttf|otf)$/,
                loader: 'file-loader',
                options: {
                    name: 'font/[name].[ext]',
                    publicPath: '../'
                }
            },
            {
                test: /\.(scss|less|css)$/,

                use: [{
                    loader: MiniCssExtractPlugin.loader
                },
                {
                    loader: 'css-loader',

                    options: {
                        sourceMap: false
                    }
                },
                {
                    loader: 'postcss-loader',
                    options: {
                        // ident: 'postcss',
                        plugins: (loader) => [
                            require('postcss-import')({ root: loader.resourcePath }),
                            // require('postcss-cssnext')(),
                            require('autoprefixer')(),

                            require('cssnano')()
                        ]
                    }
                },
                {
                    loader: 'less-loader',

                    options: {
                        sourceMap: false
                    }
                }
                ]
            }
            ]
        },
        plugins: PLUGINS,
        devServer: DEVSERVER,
        devtool: DEVTOOL,
        mode: MODE,
        // stats: {
        //     colors: true,
        //     chunks: false,
        //     chunkOrigins: false,
        //     chunkModules: false,
        //     children: false,
        //     cachedAssets: false,
        //     assets: false,
        //     entrypoints: false
        // },
        stats: 'minimal'
    }
    return ret
}
